package cn.iocoder.yudao.module.ent.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import java.util.*;

public class NodeMerger {
    public static Object mergeSimilarNodes(Object node) {
        if (!(node instanceof JSONObject) && !(node instanceof JSONArray)) {
            return node;
        }

        // 处理列表
        if (node instanceof JSONArray) {
            JSONArray nodeList = (JSONArray) node;
            List<Object> processedList = new ArrayList<>();
            for (Object item : nodeList) {
                processedList.add(mergeSimilarNodes(item));
            }

            // 合并相似的节点
            List<Object> result = new ArrayList<>();
            for (Object item : processedList) {
                boolean merged = false;
                for (Object existing : result) {
                    if (canMergeNodes(item, existing)) {
                        mergeNodes((JSONObject) existing, (JSONObject) item);
                        merged = true;
                        break;
                    }
                }
                if (!merged) {
                    result.add(item);
                }
            }
            return new JSONArray(result);
        }

        // 处理字典
        if (node instanceof JSONObject) {
            JSONObject nodeMap = (JSONObject) node;
            JSONObject result = new JSONObject();
            for (String key : nodeMap.keySet()) {
                result.put(key, mergeSimilarNodes(nodeMap.get(key)));
            }
            return result;
        }

        return node;
    }

    public static boolean canMergeNodes(Object node1, Object node2) {
        if (!(node1 instanceof JSONObject) || !(node2 instanceof JSONObject)) {
            return false;
        }

        JSONObject map1 = (JSONObject) node1;
        JSONObject map2 = (JSONObject) node2;

        Set<String> keys1 = map1.keySet();
        Set<String> keys2 = map2.keySet();

        if (!keys1.equals(keys2)) {
            return false;
        }

        for (String key : keys1) {
            if (key.equals("value") || key.equals("t")) {
                continue;
            }
            Object val1 = map1.get(key);
            Object val2 = map2.get(key);
            if (!Objects.equals(val1, val2)) {
                return false;
            }
        }
        return true;
    }

    public static void mergeNodes(JSONObject target, JSONObject source) {
        if ("is_or_not".equals(target.getStr("queryType","")) && "is_or_not".equals(source.getStr("queryType","")) && Objects.equals(target.getStr("field",""), source.getStr("field",""))) {
            return;
        }

        for (String key : source.keySet()) {
            Object value = source.get(key);

            if ("value".equals(key)) {
                if (target.containsKey(key) && target.get(key) instanceof String && value instanceof String) {
                    target.put(key, target.getStr(key) + "," + value);
                }
                continue;
            }
            if ("t".equals(key)) {
                continue;
            }
            if (value instanceof JSONObject || value instanceof JSONArray) {
                target.put(key, mergeSimilarNodes(value));
            } else {
                target.put(key, value);
            }
        }
    }

    public static void deduplicateInValues(Object node) {
        if (node instanceof JSONObject) {
            JSONObject map = (JSONObject) node;
            if ("in".equals(map.getStr("queryType","")) && map.containsKey("value")) {
                String value = map.getStr("value");
                String[] values = value.split(",");
                if(values.length > 5) {
                    values = Arrays.copyOfRange(values,0,5);
                }
                List<String> uniqueValues = new ArrayList<>(new TreeSet<>(Arrays.asList(values)));
                map.put("value", String.join(",", uniqueValues));
            }

            for (String key : map.keySet()) {
                deduplicateInValues(map.get(key));
            }
        } else if (node instanceof JSONArray) {
            JSONArray list = (JSONArray) node;
            for (Object item : list) {
                deduplicateInValues(item);
            }
        }
    }

    public static void main(String[] args) {
        // 初始化测试数据
        String jsonData = "{\n" + "    \"pageNo\": 1,\n" + "    \"pageSize\": 10,\n" + "    \"operations\": [\n" + "        {\n" + "            \"condition\": \"must\",\n" + "            \"queryFields\": [\n" + "                {\n" + "                    \"field\": \"serious_illegality_count\",\n" + "                    \"value\": \"0\",\n" + "                    \"queryType\": \"is_or_not\",\n" + "                    \"t\": 1720679921593,\n" + "                    \"id\": 823\n" + "                },\n" + "                {\n" + "                    \"field\": \"serious_illegality_count\",\n" + "                    \"value\": \"0\",\n" + "                    \"queryType\": \"is_or_not\",\n" + "                    \"t\": 1720679921595,\n" + "                    \"id\": 823\n" + "                },\n" + "                {\n" + "                    \"field\": \"entType\",\n" + "                    \"value\": \"个体工商户,普通合伙,外资,集体所有制,港澳台\",\n" + "                    \"queryType\": \"in\",\n" + "                    \"t\": 1720680130831,\n" + "                    \"condition\": \"not_in\",\n" + "                    \"id\": 310\n" + "                }\n" + "            ],\n" + "            \"operations\": [\n" + "                {\n" + "                    \"condition\": \"should\",\n" + "                    \"queryFields\": [\n" + "                        {\n" + "                            \"field\": \"patent_count\",\n" + "                            \"value\": \"1\",\n" + "                            \"queryType\": \"is_or_not\",\n" + "                            \"t\": 1720679944160,\n" + "                            \"id\": 905\n" + "                        },\n" + "                        {\n" + "                            \"field\": \"copyright_count\",\n" + "                            \"value\": \"1\",\n" + "                            \"queryType\": \"is_or_not\",\n" + "                            \"t\": 1720679953954,\n" + "                            \"id\": 911\n" + "                        }\n" + "                    ],\n" + "                    \"t\": 1720679942416,\n" + "                    \"operations\": []\n" + "                },\n" + "                {\n" + "                    \"condition\": \"should\",\n" + "                    \"queryFields\": [\n" + "                        {\n" + "                            \"field\": \"scope\",\n" + "                            \"value\": \"软件,技术,环保,计算机,通信,信息安全,智能,生物医药,器件,中药,研发,新材料,医疗,现代农业,航空,信息技术,知识产权,航天,新能源,检验,仪器仪表\",\n" + "                            \"queryType\": \"in\",\n" + "                            \"t\": 1720679967137,\n" + "                            \"condition\": \"in\",\n" + "                            \"id\": 105\n" + "                        },\n" + "                        {\n" + "                            \"field\": \"scope\",\n" + "                            \"value\": \"环保,绿色,先进设备,认证,新型材料,机器人,创意,绿化,制药,电子信息,设计,传统改造,催化剂,深加工,半导体,耐火,云计算,数据服务,自动化,网站建设\",\n" + "                            \"queryType\": \"in\",\n" + "                            \"t\": 1720680062048,\n" + "                            \"condition\": \"in\",\n" + "                            \"id\": 105\n" + "                        }\n" + "                    ],\n" + "                    \"t\": 1720679963905,\n" + "                    \"operations\": []\n" + "                }\n" + "            ]\n" + "        }\n" + "    ]\n" + "}";

        // 解析 JSON
        JSONObject data = new JSONObject(jsonData);

        // 执行合并
        Object result = mergeSimilarNodes(data);

        // 执行去重
        deduplicateInValues(result);

        // 美化输出
        System.out.println(JSONUtil.toJsonPrettyStr((JSONObject) result));
    }
}